package server.airpi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;

import player.Player.OmxPlayerCommands;
import commons.Manager;
import commons.Media;
import commons.Paths;
import commons.User;
import commons.UserList;
import commons.exceptions.PasswordException;
import commons.exceptions.ProcessException;


public class Task extends Thread{


	public final static String LOGIN = "Login";
	public final static String MEDIALIST = "MediaList";
	public final static String USERLIST = "UserList";
	public final static String PLAY = "Play";
	public final static String PAUSE = "Pause";
	public final static String NEXT = "Next";
	public final static String STOP = "Stop";
	public final static String ADMINPASS = "AdminPassword";
	public final static String GUESTPASS = "GuestPassword";
	public final static String VOLUMEUP = "VolumeUp";
	public final static String VOLUMEDOWN = "VolumeDown";
	public final static String YOUTUBE = "Youtube";
	public final static String DELETESONG = "DeleteSong";
	public final static String LOGOUT = "Logout";
	public final static String STATE = "State";

	//private final static String FINAL_PATH	= System.getProperty("user.home")+ File.separator+"airpi"+File.separator+"uploaded_files"+File.separator;
	private Server parent;
	private Socket socketduserveur;
	private BufferedReader in;
	private PrintWriter out;
	private Manager manager;

	public Task(Server server,Socket socket){
		this.parent=server;
		this.socketduserveur=socket;
		manager = Manager.getInstance();
	}

	public void run(){
		InputStream v2 = null;
		String cmd="";
		try {
			v2 = socketduserveur.getInputStream();
			byte[] buffer = new byte[50000];
			v2.read(buffer);
			String request = new String(buffer,"Cp1252");
			request = request.trim();
			System.out.println("Serveur["+new Date()+"] : Received request : " + request);
			if(request.contains(LOGIN)){
				cmd = LOGIN;
				login(request);
			}else if(request.contains(MEDIALIST)){
				cmd = MEDIALIST;
				sendMediaList();
			}else if(request.contains(USERLIST)){
				cmd = USERLIST;
				sendUserList();
			}else if(request.contains(PLAY)){
				cmd = PLAY;
				manager.play();
				send("ServerOK["+PLAY+"]");
			}else if(request.contains(PAUSE)){
				cmd = PAUSE;
				manager.pause();
				send("ServerOK["+PAUSE+"]");
			}else if(request.contains(STOP)){
				cmd = STOP;
				manager.stopMedia();
				send("ServerOK["+STOP+"]");
			}else if(request.contains(NEXT)){
				cmd = NEXT;
				manager.next();
				send("ServerOK["+NEXT+"]");
			}else if(request.contains(ADMINPASS)){
				cmd = ADMINPASS;
				changeAdminPassword(request);
			}else if(request.contains(GUESTPASS)){
				cmd = GUESTPASS;
				changeGuestPassword(request);
			}else if(request.contains(VOLUMEUP)){
				cmd = VOLUMEUP;
				manager.action(OmxPlayerCommands.INCREASE_VOLUME.getCommand());
				send("ServerOK["+VOLUMEUP+"]");
			}else if(request.contains(VOLUMEDOWN)){
				cmd = VOLUMEDOWN;
				manager.action(OmxPlayerCommands.DECREASE_VOLUME.getCommand());
				send("ServerOK["+VOLUMEDOWN+"]");
			}else if(request.contains(YOUTUBE)){
				cmd = YOUTUBE;
				addYoutubeLink(request);
			}else if(request.contains(STATE)){
				cmd = STATE;
				int a = (manager.isPlaying()) ? 1 : 0;
				int b = (manager.isStopped()) ? 1 : 0;
				send("ServerOK["+STATE+"]:"+a+";"+b);
			}else if(request.contains(DELETESONG)){
				cmd = DELETESONG;
				deleteSong(request);
			}else if(request.contains(LOGOUT)){
				cmd = LOGOUT;
				logout(request);
			}
			v2.close();
			socketduserveur.close();
		}catch (IOException e) {
			send("ServerKO["+cmd+"]");
			System.err.println("Serveur["+new Date()+"] : Error : "+e.getMessage());
		} catch (ProcessException e) {
			send("ServerKO["+cmd+"]");
			System.err.println("Serveur["+new Date()+"] : Error : "+e.getMessage());
		} finally{
			try {
				v2.close();
				parent.logout();
			} catch (IOException e) {
			}
		}
	}


	private void login(String request){
		request = request.substring(6);
		String[] content = request.split(";");
		String login = content[0];
		String password = content[1].substring(0,4);
		try {
			if(User.sayTrueIfThisIsTheAdminPasswordOrFalseIfThisIsTheGuestPasswordOrExceptionIfItIsArandomString(password)){
				User user = new User(login,true);
				manager.addUser(user);
				send("ServerOK["+LOGIN+"]:admin"+user.getIdSession());
			}else{
				User user = new User(login,false);
				manager.addUser(user);
				send("ServerOK["+LOGIN+"]:guest"+user.getIdSession());
			}
		} catch (PasswordException e){
			System.err.println("Serveur["+new Date()+"] : Error : "+e.getMessage());
			send("ServerKO["+LOGIN+"]");
		} catch (IllegalArgumentException e) {
			System.err.println("Serveur["+new Date()+"] : Error : "+e.getMessage());
			send("ServerKO["+LOGIN+"]");
		} catch (ProcessException e) {
			System.err.println("Serveur["+new Date()+"] : Error : "+e.getMessage());
			send("ServerKO["+LOGIN+"]");	
		}

	}



	private void sendMediaList(){
		Media[] list = manager.getMediaList().getMediaListTab();
		String res="";
		for(int i = 0;i<list.length;i++){
			if(list[i].getTitle().length()>0){
				res+=list[i].getTitle()+";"+list[i].getDuration()+";"+list[i].getUser().getName()+"/";
			}else{
				res+=list[i].getMediaName()+";;"+list[i].getUser().getName()+"/";
			}
		}
		System.out.println(res);
		send("ServerOK["+MEDIALIST+"]:"+res);
	}

	private void sendUserList(){
		UserList list = manager.getUserList();
		send("ServerOK["+USERLIST+"]:"+list.getUserListString());
	}


	private void changeGuestPassword(String request) {
		try {
			String tmp = request.trim().substring(14);
			String [] args = tmp.split(";");
			manager.changeGuestPassword(args[0], args[1]);
			send("ServerOK["+GUESTPASS+"]:guest");
		} catch (PasswordException e) {
			System.out.println(e.getMessage());
			send("ServerKO["+GUESTPASS+"]");
		}
	}

	private void changeAdminPassword(String request) {
		try {
			String tmp = request.trim().substring(14);
			String [] args = tmp.split(";");
			manager.changeAdminPassword(args[0], args[1]);
			send("ServerOK["+ADMINPASS+"]:admin");
		} catch (PasswordException e) {
			send("ServerKO["+ADMINPASS+"]");
		}
	}


	private void addYoutubeLink(String request) {
		String[] tmp = request.substring(8).split(";");
		String url = tmp[0].trim();
		System.out.println("URL = " + url);
		url = url.split("&")[0];
		System.out.println("URL = " + url);
		String tmp1 = tmp[1].trim();
		User user = manager.getUserList().getUser(tmp1);
		if(user!=null && !(url.equals(""))){
			Media media = Media.createMediaFromLink(url,user,Paths.AIRPI_UPLOADED_FILES);
			if(media==null){
				System.out.println("Return a media null");
				send("ServerKO[Youtube]"); 
			}else{	
				System.out.println("Return a media: "+media.getMediaName());
				manager.addMedia(media);
				send("ServerOK[Youtube]");
			}
		}else{
			send("ServerKO[Youtube]");
		}
	}


	private void deleteSong(String request){
		try {
			String[] tmp = request.substring(11).split(";");
			String title = tmp[0];
			Media media = manager.getMediaList().searchByString(title);
			if(media==null) media = manager.getMediaList().searchByTitle(title);
			if(media!=null){
				manager.delMedia(media);
				send("ServerOK["+DELETESONG+"]");
			}else{
				send("ServerKO["+DELETESONG+"]");
			}
		} catch (ProcessException e) {
			send("ServerKO["+DELETESONG+"]");
		}
	}


	private void logout(String request){
		String userString = request.split(";")[1].trim();
		User user = manager.getUserList().getUser(userString);
		if(user != null) manager.delUser(user);
		send("ServerOK["+LOGOUT+"]");
	}


	public void send(String msg){
		try {
			out = new PrintWriter(socketduserveur.getOutputStream());
			out.println(msg);
			out.flush();
			System.out.println(msg);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void closeConnection() throws IOException {
		out.close();
		in.close();
		socketduserveur.close();
		parent.logout();
	}
}